<template>
    <el-dialog draggable :close-on-click-modal="false" class="yy-modal--custom" width="800px" v-model="isVisible" @close="onCancelModel" :show-close="true">
        <template #header="{ close, titleId, titleClass }">
            <h4 :id="titleId" :class="titleClass">插播计划</h4>
        </template>
        <div class="yy-play-schedule_edit-content">
            <div class="yy-play-schedule_edit-page">
                <div class="yy-play-schedule_edit-header" v-if="!originData" style="display: flex; justify-content: space-between;">
                    <label>
                        <span>计划周期：</span>
                        <el-date-picker
                                v-model="selectDateArr"
                                type="daterange"
                                range-separator="-"
                                start-placeholder="开始日期"
                                end-placeholder="结束日期"
                                @change="onGenerateSchedule"
                        />
                    </label>
                    <label>
                        <span>时间间隔：</span>
                        <span>
                          <el-select  placeholder="类型" v-model="timeInterval.type" style="width: 60px" @change="onIntervalTypeChange">
                            <el-option label="天" value="date" />
                            <el-option label="时" value="hour" />
                            <el-option label="分" value="minute" />
                          </el-select>
                          <el-select  placeholder="时长" v-model="timeInterval.value" style="width: 80px" @change="onGenerateSchedule">
                            <el-option v-for="interval in typeIntervalMap[timeInterval.type]" :label="interval" :value="interval"/>
                          </el-select>
                        </span>
                    </label>
                </div>
                <div class="yy-play-schedule_edit-items">
                    <WidgetTable
                            :is-loading="table.isLoading"
                            :columns="table.columns"
                            :data="table.data"
                            :options="table.options"
                            :formats="table.formats"
                            :paging-data="table.paging"
                    >
                      <template v-slot:startDate="{row, column}">
                        <div style="display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;">
                          <el-date-picker
                              v-model="row.startTime"
                              format="YYYY-MM-DD HH:mm"
                              date-format="YYYY-MM-DD"
                              time-format="HH:mm"
                              type="datetime"
                          />
                        </div>
                      </template>
                      <template v-slot:endDate="{row, column}">
                        <div style="display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;">
                          <el-date-picker
                              v-model="row.endTime"
                              format="YYYY-MM-DD HH:mm"
                              date-format="YYYY-MM-DD"
                              time-format="HH:mm"
                              type="datetime"
                          />
                        </div>
                      </template>
                      <template v-slot:template="{row, column}">
                            <div style="display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;">
                                <el-select
                                        placeholder="请选择模板"
                                        automatic-dropdown
                                        :clearable="true"
                                        :filterable="true"
                                        remote
                                        reserve-keyword
                                        remote-show-suffix
                                        :remote-method="onSearchTemplate"
                                        v-model="row.templateId"
                                        @change="onSelectTemplate(row)"
                                >
                                    <el-option
                                            v-for="item in templateList"
                                            :key="item.id"
                                            :label="item.name"
                                            :value="item.id"
                                    />
                                </el-select>
                            </div>
                        </template>
                      <template v-slot:action="{row, column}">
                        <div class="yy-play-schedule_edit-items-action">
                          <span v-if="table.data.length > 1" class="yy-play-schedule_edit-items-action--del" @click="onRemoveItem(row.id)"><el-icon ><Remove /></el-icon></span>
                          <span class="yy-play-schedule_edit-items-action--add" @click="onAddSelectItem(row.id)"><el-icon ><CirclePlus /></el-icon></span>
                        </div>
                      </template>
                    </WidgetTable>
                </div>
            </div>
            <div class="yy-play-schedule_edit-page" style="margin-top: 15px;">
                <WidgetForm ref="scheduleFormRef" :form-fields="dialog.formFields" />
            </div>
        </div>
        <template #footer>
        <span class="dialog-footer">
          <el-button @click="onCancelModel">关闭</el-button>
          <el-button type="primary" :loading="isLoading" @click="onSaveSchedule">保存</el-button>
        </span>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">

import {defineExpose, nextTick, onBeforeMount, reactive,defineEmits, ref} from "vue";
import {ElButton, ElDialog, ElMessage, ElSelect} from "element-plus";
import {EnvConfig, formatDate} from "@/utils/index.js";
import WidgetTable from "@/components/widget/WidgetTable.vue";
import {TableColumn, WidgetFormField} from "@/model/Definition";
import WidgetForm from "@/components/widget/WidgetForm.vue";
import {BaseModel} from "@/model/BaseModel";
import ScheduleApi from "@/api/broadcast/schedule";
import {useRouter} from "vue-router";
import {BcTemplateModel} from "@/model/BcTemplateModel";
import {BcScheduleModel} from "@/model/BcScheduleModel";
import TemplateApi from "@/api/broadcast/template";

const isVisible = ref(false)
const isLoading = ref(false)
const originData = ref()
let currentDeptId = null
const router = useRouter()

const $emit = defineEmits({
    editCallback: ((data: BaseModel) => data),
})


const typeIntervalMap = {
    'date': [1, 2, 3, 5, 7, 10, 14, 30],
    'hour': [1, 6, 12, 24],
    'minute': [15, 30, 60]
}

const templateList = ref<BcTemplateModel[]>([])
const selectDateArr = ref([])
const timeInterval = reactive({
    value: 1,
    type: 'date'
})

const table = reactive<{
    isLoading: boolean,
    paging: any,
    columns: TableColumn[],
    data: any[],
    options?: any,
    formats?: any
}>({
    isLoading: false,
    columns: [
        {
            "field":"index",
            "label":"序号",
            "type": "index",
            "showable":true,
            "fixed": 'left',
            "align": 'center',
            "width": 45
        },
        {
            "field":"startDate",
            "label":"开始时间",
            "showable":true,
            "width": 180
        },
        {
            "field":"endDate",
            "label":"结束时间",
            "showable":true,
            "width": 180
        },
        {
            "field":"template",
            "label":"选择节目",
            "showable":true,
        },
        {
            "field":"action",
            "label":"操作",
            "width": 120,
            "showable":true,
            "align": 'center',
            "fixed": 'right'
        }
    ],
    paging: {
        isPaging: false,
    },
    options: {
        highlight: true
    },
    data: [],
    formats: {
        'startDate': {
          slot: 'startDate',

        },
        'endDate': {
          slot: 'endDate',

        },
        'template': {
            slot: 'template'
        },
        'action': {
           slot: 'action'
        }
    }
})
const scheduleFormRef = ref()
const dialog = reactive<{formFields: WidgetFormField[],modelInstance?: BaseModel, saveApiFun?: any, updateApiFun?: any}>({
    formFields: [
        {field: 'name', label: '计划名称', type: 'text', placeholder: '请输入名称', required: [{required: true, message: '名称不能为空', trigger: 'blur'}]},
        {field: 'description', label: '描述', type: 'textarea'},
    ]
})


onBeforeMount(() => {
    onSearchTemplate()
})

const onIntervalTypeChange = () => {
    if (timeInterval.type === 'date') {
        timeInterval.value = 1
    } else if(timeInterval.type === 'hour') {
        timeInterval.value = 12
    } else {
        timeInterval.value = 30
    }
    onGenerateSchedule()
}

const onGenerateSchedule = () => {
    if (selectDateArr.value?.length && timeInterval.value && timeInterval.type) {
        let data = []
        const startDateTime = new Date(selectDateArr.value[0].getFullYear(), selectDateArr.value[0].getMonth(), selectDateArr.value[0].getDate(), 0, 0, 0).getTime()
        const endDateTime = new Date(selectDateArr.value[1].getFullYear(), selectDateArr.value[1].getMonth(), selectDateArr.value[1].getDate(), 23, 59, 59).getTime()

        // 按天
        if (timeInterval.type === 'date') {
            data = _getDateRange(new Date(startDateTime), new Date(endDateTime))
        }
        // 按小时
        else if (timeInterval.type === 'hour') {
            data = _getHoursRange(new Date(startDateTime), new Date(endDateTime))
        }
        else {
            data = _getMinutesRange(new Date(startDateTime), new Date(endDateTime))
        }
        table.data = data
      console.log('data:', data)
    }
}

const _getMinutesRange = (startDate: Date, endDate: Date) => {
    let dates = [];
    let currentDate = startDate;
    while (currentDate <= endDate) {
        let start = new Date(currentDate.getTime());
        let hours = start.getHours()
        let minute = start.getMinutes()

        currentDate.setMinutes(currentDate.getMinutes() + +timeInterval.value);
        let endHours = currentDate.getHours()
        let endMinute = currentDate.getMinutes()
        dates.push({
            startDate: formatDate(start.getTime(), 'YYYY-MM-DD'),
            endDate: formatDate(currentDate.getTime(), 'YYYY-MM-DD'),
            start: String(hours).padStart(2, '0') + ':'+String(minute).padStart(2, '0'),
            end: String(endHours).padStart(2, '0') + ':'+String(endMinute).padStart(2, '0'),
            startTime: new Date(formatDate(start.getTime(), 'YYYY-MM-DD') + " " + String(hours).padStart(2, '0') + ':'+String(minute).padStart(2, '0') + ":00").getTime(),
            endTime: new Date(formatDate(currentDate.getTime(), 'YYYY-MM-DD') + " " + String(endHours).padStart(2, '0') + ':'+String(endMinute).padStart(2, '0') + ":59").getTime(),
        });
    }
    return dates
}


const _getHoursRange = (startDate: Date, endDate: Date) => {
    let dates = [];
    let currentDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate(),startDate.getHours(), 0, 0);
    while (currentDate <= endDate) {
        let start = new Date(currentDate.getTime());
        let hours = start.getHours()
        currentDate.setHours(currentDate.getHours() + +timeInterval.value);
        let end  = new Date(currentDate.getTime())
        end.setSeconds(end.getSeconds() - 1);
        dates.push({
            startDate: formatDate(start.getTime(), 'YYYY-MM-DD'),
            endDate: formatDate(end.getTime(), 'YYYY-MM-DD'),
            start: String(hours).padStart(2, '0') + ':00',
            end: String(end.getHours()).padStart(2, '0') + ':59',
            startTime: new Date(formatDate(start.getTime(), 'YYYY-MM-DD') + " " + String(hours).padStart(2, '0') + ':00:00').getTime(),
            endTime: new Date(formatDate(end.getTime(), 'YYYY-MM-DD') + " " + String(end.getHours()).padStart(2, '0') + ':59:59').getTime(),
        });
    }
    return dates
}

const _getDateRange = (startDate: Date, endDate: Date) => {
    let dates = [];
    let currentDate = startDate;
    while (currentDate <= endDate) {
        let start = new Date(currentDate.getTime());
        currentDate.setDate(currentDate.getDate() + +timeInterval.value);
        let end = new Date(currentDate.getTime());
        if (currentDate > endDate) {
            end = endDate
        }
        end.setSeconds(end.getSeconds() - 1)
        dates.push({
            startDate: formatDate(start.getTime(), 'YYYY-MM-DD'),
            endDate: formatDate(end.getTime(), 'YYYY-MM-DD'),
            start: '00:00',
            end: '23:59',
            startTime: new Date(formatDate(start.getTime(), 'YYYY-MM-DD') + " " + "00:00:00").getTime(),
            endTime: new Date(formatDate(end.getTime(), 'YYYY-MM-DD') + " " + "23:59:59").getTime(),
        });
    }
    return dates
}


const onSearchTemplate = (searchKey: string = null) => {
    TemplateApi.listTemplate(searchKey, null,1, +EnvConfig.pageSize).then((res: any) => {
        templateList.value = res.data
    })
}

const onShowDialog = (deptId: string, data: BcScheduleModel) => {
    currentDeptId = deptId
    isVisible.value = true
    if (data) {
        originData.value = data
        nextTick(() => {
            try {
                if (data.config) {
                    const templateOptions = []
                    const configs = JSON.parse(data.config)
                    table.data = configs.map(item => {
                        templateOptions.push({name: item.templateName, id: item.templateId})
                        return Object.assign({}, item, {
                            id: getRowId(),
                            startDate: formatDate(new Date(item.startTime * 1000), 'YYYY-MM-DD'),
                            start: formatDate(new Date(item.startTime * 1000), 'HH:mm'),
                            endDate: formatDate(new Date(item.endTime * 1000), 'YYYY-MM-DD'),
                            end: formatDate(new Date(item.endTime * 1000), 'HH:mm'),
                            startTime: item.startTime * 1000,
                            endTime: item.endTime * 1000
                        })
                    })
                    templateList.value = templateOptions
                }
            } catch (ex){}
            scheduleFormRef.value.initFormData(data)
        })
    } else {
      nextTick(() => {
        table.data =  [{
          id: getRowId(),
          startDate: formatDate(new Date(), 'YYYY-MM-DD'),
          start: formatDate(new Date(), 'HH:mm'),
          endDate: formatDate(new Date(), 'YYYY-MM-DD'),
          end: formatDate(new Date(), 'HH:mm'),
          startTime: new Date(formatDate(new Date().getTime(), 'YYYY/MM/DD') + " " + "00:00:00").getTime(),
          endTime: new Date(formatDate(new Date().getTime(), 'YYYY/MM/DD') + " " + "23:59:59").getTime(),
        }]
      })
    }
}


const onAddSelectItem = (id: string) => {
  const index = table.data.findIndex(item => item.id === id)
  if (index >= 0) {
    if (index < table.data.length - 1) {
      table.data.splice(index + 1, 0, {
        id: getRowId(),
        startDate: formatDate(new Date(), 'YYYY-MM-DD'),
        start: formatDate(new Date(), 'HH:mm'),
        endDate: formatDate(new Date(), 'YYYY-MM-DD'),
        end: formatDate(new Date(), 'HH:mm'),
        startTime: new Date(formatDate(new Date().getTime(), 'YYYY/MM/DD') + " " + "00:00:00").getTime(),
        endTime: new Date(formatDate(new Date().getTime(), 'YYYY/MM/DD') + " " + "23:59:59").getTime(),
      })
    } else {
      table.data.push({
        id: getRowId(),
        startDate: formatDate(new Date(), 'YYYY-MM-DD'),
        start: formatDate(new Date(), 'HH:mm'),
        endDate: formatDate(new Date(), 'YYYY-MM-DD'),
        end: formatDate(new Date(), 'HH:mm'),
        startTime: new Date(formatDate(new Date().getTime(), 'YYYY/MM/DD') + " " + "00:00:00").getTime(),
        endTime: new Date(formatDate(new Date().getTime(), 'YYYY/MM/DD') + " " + "23:59:59").getTime(),
      })
    }
  }
}

const onRemoveItem = (id: string) => {
  const index = table.data.findIndex(item => item.id === id)
  if (index >= 0) {
    table.data.splice(index, 1)
  }
}

const onSelectTemplate = (row: any) => {
    const template = templateList.value.find(item => item.id === row.templateId)
    row.templateName = template.name
    // getTemplateParams(template)
}

const onSaveSchedule = () => {
    const scheduleData = table.data
    scheduleFormRef.value.validateForm((valid) => {
        if (valid) {
            const formData = scheduleFormRef.value.getFormFieldValue()
            const configs = scheduleData.map(item => Object.assign({startTime: item.startTime / 1000, endTime: item.endTime / 1000, templateId: item.templateId, templateName: item.templateName}))
            const schedule = new BcScheduleModel().deserialize({
                id: originData.value?.id || undefined,
                name: formData.name,
                deptId: currentDeptId,
                description: formData.description,
                config: JSON.stringify(configs)
            })
            if (originData.value) {
                ScheduleApi.updateSchedule(originData.value.id, schedule).then((res) => {
                    $emit('editCallback', res)
                    onCancelModel()
                })
            } else {
                ScheduleApi.saveSchedule(schedule).then((res) => {
                    $emit('editCallback', res)
                    onCancelModel()
                })
            }

        }
    })
}

const onCancelModel = () => {
  if (isVisible.value) {
      originData.value = null
      table.data = []
      scheduleFormRef.value.resetFields()
  }
  isVisible.value = false
}
const getRowId = () => {
  return new Date().getTime() + '_' + Math.random()
}
defineExpose({
  onShowDialog
})
</script>
<style scoped lang="scss">
.yy-play-schedule_edit {
  width: 100%;
  height: 100%;
  &-header{
    margin-bottom: 20px;
  }

  &-items {
    &-action {
      cursor: pointer;
      font-size: 16px;
      &--del {
        color: #e81123;
      }
      &--add {
        margin-left: 8px;
        color: #009688;
      }
    }
  }
}
</style>
